<template>
	<view class="container">
		<!-- <liveComponent ></liveComponent> -->

		<view class="video">
			<video id="myVideo" style="position: relative;" :show-mute-btn="show_mute_btn"
				:enable-play-gesture="enable_play_gesture" :show-center-play-btn="show_center_play_btn"
				:page-gesture="page_gesture" :src="videoUrl" controls @timeupdate="timeupdate"
				:initial-time="initialTime" @play="play" @pause="pause" @ended="ended">
				<cover-image v-if="isSmartMonitor" @click="start"
					style="width: 34rpx;height: 34rpx;background-color: red;position: absolute;left: 30rpx;top: 372rpx;opacity: 0 !important;">
					<!-- <button  >开始推流</button>方法 -->
				</cover-image>
			</video>
		</view>
		<view class="content">
			<scroll-view scroll-x="true" class='scroll-content' :scroll-into-view='scrollIntoIndex'>
				<view :id="'top'+index" class='scroll-item' v-for='(item,index) in topBar' :key='index'
					@tap='changeTab(index)'>
					<text :class='topBarIndex===index? "f-active-color":"f-color"'>{{item.name}}</text>
				</view>
				<view class='scroll-item' @click="test">
					<!-- <text @click="test">AI伴学</text> -->
					<uni-fav :checked="checkList[4]" class="favBtn" :star="false" :circle="true" @click="favClick(4)"
						:content-text="contentText" />
				</view>

			</scroll-view>
			<swiper @change="onChangeTab" :current="topBarIndex" :style="{height:clentHeight + 'px'}">
				<swiper-item>
					<view class="home-data">
						<scroll-view scroll-y="true" style="height: 63vh;">


							<view class="lessons">
								<view class="lessons_item" v-for="item in chapterArr">
									<view class="lessons_title">
										{{item.chapterName}}
									</view>
									<view class="lessons_content" v-for="i in item.courseVideos">
										<text type="" class="icon-daima"
											:class="i.courseResourceId == chapter.courseResourceId ? 'selected' : '' "
											@click="selectSidebar(i.courseResourceId)">{{i.title}}</text>
									</view>
								</view>

								<view class="fill" style="height:8vh;">

								</view>
							</view>
						</scroll-view>
						<view class="content-bottom">
							<button v-if="isJoined" disabled>已添加本课程</button>
							<button @click="getUserLike" v-else type="primary">添加课程</button>
						</view>
					</view>
				</swiper-item>
				<swiper-item>
					<view class="course-data">
						<scroll-view scroll-y="true" style="height: 63vh;">
							<view class="lessons">
								<text class="lessons_title">授课时长<br /><br /></text>
								<text class="lessons_content">{{courseIntroduceInfo.classHour}}<br /><br /></text>
								<text class="lessons_title">课程介绍<br /><br /></text>
								<text
									class="lessons_content">{{courseIntroduceInfo.courseIntroduction}}<br /><br /></text>
								<text class="lessons_title">课程重难点</text>
								<markdown :markdown="courseIntroduceInfo.keyAndDifficultPoints"></markdown>
							</view>
						</scroll-view>
					</view>
				</swiper-item>
				<swiper-item>
					<view class="remark-data">
						<view class="bottom">
							<!-- <input class="bottom-input" name="name" placeholder="请输入" @input="remarkInput"
								v-model="aremark" />
							<button class="bottom-button" type="primary" @click="onSend">发送</button> -->
							<input class="bottom-input" name="name" placeholder="请输入你的想法..." v-model="comment" />
							<button class="bottom-button" type="primary" @click="post">发送</button>
						</view>
						<scroll-view scroll-y="true" style="height: 55vh;">


							<view class="content">
								<view class="">
									<!-- <scroll-view scroll-y="true"> -->
									<view class="remarkarea">
										<view class="title">
											<text>AI精选</text>
										</view>

										<!-- <uni-card :is-shadow="false">
											<text class="uni-body">这是一个基础卡片示例，内容较少，此示例展示了一个没有任何属性不带阴影的卡片。</text>
										</uni-card> -->

										<view class="remarkcontent">
											<view class="hasContant">
												<!-- <uni-section type="line"> -->
												<!-- <uni-card :is-shadow="false"> -->
												<text class="uni-body">{{aijx}}</text>
												<!-- </uni-card> -->
												<!-- </uni-section> -->
											</view>
										</view>

										<view class="title">
											<text>评论区</text>
										</view>
										<view class="remarkcontent">
											<view class="hasContant" v-for="(item,index) in commentArr"
												:key="item.createrId">
												<view class="left">
													<image :src="item.picUrl" mode="aspectFill"></image>
												</view>
												<view class="right">
													<!-- 名字 -->
													<view class="">

													</view>
													<!-- 内容 -->
													<view class="remark">
														<text style="color: orange; font-weight: bold; margin:
															0; font-size: 15px;">{{item.userName}}<br /></text>
														<text style="padding: 10rpx 0;">{{item.context}}<br /></text>
														<text
															style="font-size: 12px; color: #666;">{{item.updateTime}}<br /></text>
													</view>

													<!-- 日期 -->

												</view>
											</view>

										</view>
									</view>
									<!-- </scroll-view> -->
								</view>
							</view>
						</scroll-view>

					</view>
				</swiper-item>

				<!-- 笔记 -->
				<swiper-item>
					<view class="note-data">
						<scroll-view scroll-y="true" style="height: 63vh;">
							<view class="noteTitle">
								<view class="title">
									标题
								</view>
								<view class="content">
									<input type="text" placeholder="请输入笔记标题" v-model="note.docTitle" />
								</view>
							</view>
							<view class="noteZhaiyao">
								<view class="title">
									摘要
								</view>
								<view class="content">
									<textarea name="" id="" placeholder="请输入笔记摘要" v-model="note.docSummary"></textarea>
								</view>
							</view>
							<view class="noteContent">
								<view class="title">
									内容
								</view>

								<view class="lessons">
									<view class="container">
										<view class="page-body">
											<view class='wrapper'>
												<view class='toolbar' @tap="format"
													style="height: 120px;overflow-y: auto;">
													<view :class="formats.bold ? 'ql-active' : ''"
														class="iconfont icon-zitijiacu" data-name="bold">
													</view>
													<view :class="formats.italic ? 'ql-active' : ''"
														class="iconfont icon-zitixieti" data-name="italic">
													</view>
													<view :class="formats.strike ? 'ql-active' : ''"
														class="iconfont icon-zitishanchuxian" data-name="strike"></view>

													<view :class="formats.align === 'center' ? 'ql-active' : ''"
														class="iconfont icon-juzhongduiqi" data-name="align"
														data-value="center"></view>
													<view :class="formats.align === 'right' ? 'ql-active' : ''"
														class="iconfont icon-youduiqi" data-name="align"
														data-value="right">
													</view>
													<view :class="formats.align === 'justify' ? 'ql-active' : ''"
														class="iconfont icon-zuoyouduiqi" data-name="align"
														data-value="justify"></view>

													<view :class="formats.marginTop ? 'ql-active' : ''"
														class="iconfont icon-722bianjiqi_duanqianju"
														data-name="marginTop" data-value="20px"></view>
													<view :class="formats.marginBottom ? 'ql-active' : ''"
														class="iconfont icon-723bianjiqi_duanhouju"
														data-name="marginBottom" data-value="20px"></view>

													<view :class="formats.fontFamily ? 'ql-active' : ''"
														class="iconfont icon-font" data-name="fontFamily"
														data-value="Pacifico"></view>
													<view :class="formats.fontSize === '24px' ? 'ql-active' : ''"
														class="iconfont icon-fontsize" data-name="fontSize"
														data-value="24px"></view>

													<view :class="formats.color === '#0000ff' ? 'ql-active' : ''"
														class="iconfont icon-text_color" data-name="color"
														data-value="#0000ff"></view>
													<view
														:class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
														class="iconfont icon-fontbgcolor" data-name="backgroundColor"
														data-value="#00ff00"></view>


													<view class="iconfont icon-undo" @tap="undo"></view>
													<view class="iconfont icon-redo" @tap="redo"></view>


													<view class="iconfont icon-charutupian" @tap="insertImage"></view>

												</view>


												<!-- 文本区域 -->
												<view class="editor-wrapper">
													<editor id="editor" class="ql-container" placeholder="输入内容详情..."
														show-img-size show-img-toolbar show-img-resize
														@statuschange="onStatusChange" :read-only="readOnly"
														@ready="onEditorReady">
													</editor>
												</view>
											</view>
										</view>
									</view>
								</view>
								<view class="buttonarea">
									<button @click="polish">AI润色</button>
									<button @click="save">保存笔记</button>
									<button @click="correct">AI纠错</button>
								</view>

							</view>
						</scroll-view>
					</view>
				</swiper-item>
			</swiper>

		</view>
		<!-- 好像是把这个录像页面放到这个位置 就不会让录像页面单独显现出来了，如果放到视频最上面，视频元素会被往下挤压 ，放到swiper下面则是无法调用摄像头-->
		<view class="live" v-if="isSmartMonitor">
			<live-pusher id='livePusher' ref="livePusher" class="livePusher" :url="url" mode="SD" :muted="false"
				:enable-camera="true" :auto-focus="true" :beauty="0" whiteness="0" aspect="9:16"
				@statechange="statechange" @netstatus="netstatus" @error="error"></live-pusher>
			<!-- :device-position="front" :enable-mic="true" -->
			<!-- <button class="btn" @click="stop">停止推流</button> -->
			<!-- <button class="btn" @click="switchCamera">切换摄像头</button> -->
		</view>
		<uni-popup ref="answerpopup" type="bottom">
			<view class="answerpop">
				<view class="header">
					<view></view>
					<view class="title">
						课程问答
					</view>
					<view class="close" @click="closer">
						<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
					</view>
				</view>
				<view class="box">
					<view class="ask">
						<input type="text" placeholder="请输入有关本课程的问题" v-model="question" />
						<button @click="aiStartInitiative()">发送</button>
					</view>
				</view>
				<scroll-view scroll-y="true">
					<view class="content">


						<view class="answer">
							<!-- {{courseAskAnswer}} -->
							<markdown :markdown="courseAskAnswer"></markdown>
						</view>
					</view>
				</scroll-view>
			</view>
		</uni-popup>

		<uni-popup ref="quickPositionpopup" type="bottom">
			<view class="answerpop">
				<view class="header">
					<view></view>
					<view class="title">
						快速定位
					</view>
					<view class="close" @click="closer">
						<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
					</view>
				</view>
				<view class="box">
					<view class="" v-if="isPosition">
						<uni-pagination :show-icon="true" :total="totalLength" value="0" title="标题文字"
							@change="preOrNext" />
					</view>
					<view class="ask" v-else>
						<input type="text" placeholder="请输入当前视频中的关键字" v-model="position" />
						<button @click="quickPositionMethod()">发送</button>
					</view>
				</view>

			</view>
		</uni-popup>

		<uni-popup ref="infopopup" type="bottom">
			<view class="infopop">
				<view class="header">
					<view></view>
					<view class="title">
						视频总结
					</view>
					<view class="close" @click="closer">
						<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
					</view>
				</view>
				<scroll-view scroll-y="true">
					<!-- <text>{{videoSummary}}</text> -->
					<markdown :markdown="videoSummary"></markdown>
				</scroll-view>
			</view>
		</uni-popup>

		<view>
			<!-- 提示窗示例  ai纠错的 -->
			<uni-popup ref="alertDialog" type="dialog">
				<uni-popup-dialog :type="msgType" title="AI纠错" :content="aiJCContent" @confirm="dialogConfirm"
					@close="dialogClose"></uni-popup-dialog>
			</uni-popup>
		</view>

		<view>
			<!-- 疲劳监测 -->
			<uni-popup ref="alertDialogPiLao" type="dialog">
				<uni-popup-dialog :type="msgType" title="疲劳监测" :content="pLJCContent" @confirm="dialogConfirmPL"
					@close="dialogClosePL"></uni-popup-dialog>
			</uni-popup>
		</view>


		<AI :onAskAnswer="onAskAnswer" :onQuickPosition="onQuickPosition" :onSummary="onSummary" :onAIOpen="onAIOpen">
		</AI>
	</view>


</template>

<script>
	export default {
		data() {
			return {
				intervalId: null,
				// 循环判断用户在开启监测后,系统监测到用户困惑或其他监测后,用户点击了取消而继续学习的操作
				intervalIdIsBeiJieCeLa: null,
				intervalIdIsQvXiao: null,
				isPusher: false,
				url: 'rtmp://121.40.57.89/live/livestream'
			}
		},
		// props: {
		// 	isMonitor: {
		// 		type: Boolean,
		// 		required: true
		// 	}
		// },
		onReady() {
			this.context = uni.createLivePusherContext("livePusher", this);
			this.videoContext = uni.createVideoContext('myVideo');
		},
		methods: {
			// 视频开始播放和停止播放的方法
			videoPlay(e) {
				this.videoContext.play();
				// 要统一处理 监测到用户困惑或疲劳时,用户点击取消的情况
				// 点击取消,那么就要重新开始推流,或者是直接执行play方法
				// 因为暂停推流后,后端不会再给你返回对应的请求
				// 而你的流好像是已经连接成功的
				// 加一个标志    往本地
				// 如果是确认点击取消后的true 那么就让它重新建立推流操作 
				console.log("视频开始播放");

				// 这里的判断 不行 用户在vue3中点击取消后 不会触发这里的视频播放
				// 之前可以触发 完全是靠用户手动点击视频播放按钮的

				// setTimeout(() => {
				// 	console.log("用户点击取消继续学习3s后 开始重新建立连接")
				// 	// 通过flag1=false 来确定用户在vue3中点击了取消 错
				// 	// 是用来判断是否是被监测到 了
				// 	if (!uni.getStorageSync("flag1")) {

				// 		this.start()
				// 	}
				// }, 3000)
			},
			videoPause(e) {
				this.videoContext.pause();
				// 停流操作
				// this.stop()
				console.log("视频暂停播放");
			},





			statechange(e) {
				// console.log("statechange:" + JSON.stringify(e));
			},
			netstatus(e) {
				// console.log("netstatus:" + JSON.stringify(e));
			},
			error(e) {
				console.log("error:" + JSON.stringify(e));
			},
			start() {
				// 在这里 要实现推流和切换摄像头
				// 要加一个标志flag  这样如果是推 就true
				// 下次点击后就是变回false 执行停流的操作
				this.isPusher = !this.isPusher;
				console.log("是否推流：", this.isPusher);
				// 如果是true 执行推流
				if (this.isPusher) {
					// this.isPusher = 
					// 让视频先播放
					this.videoPlay();

					this.switchCamera();
					// this.context.switchCamera({
					// 	success: (a) => {
					// 		console.log("livePusher.switchCamera:" + JSON.stringify(a));
					// 	}
					// });


					// getUserAction()
					// 正式推流的操作（先等getUserAction请求发送后的3s后再推，给python一个启动对应服务的时间）
					// setTimeout(() => {
					this.context.start({
						success: (a) => {
							// console.log("livePusher.start:" + JSON.stringify(a));
						}
					})
					// 给一个推流前成功发送请求的flag为true

					// }, 500)

					this.streamLinked()


				} else {
					this.switchCamera();
					// 执行停流
					this.stop();
					// 再停止视频播放
					this.videoPause();
					// this.context.stop({
					// 	success: (a) => {
					// 		console.log(JSON.stringify(a));
					// 	}
					// });
				}
			},
			// 判断用户是否被监测到疲劳或困惑？就停流
			beiJieCeLa() {
				this.intervalIdIsBeiJieCeLa = setInterval(() => {
					// console.log("用户是否被监测到了困惑1？")
					if (!uni.getStorageSync("flag1")) {
						console.log("用户是否被监测到了困惑2？") //一直定时判断 直到拿到flag1=flase才停
						this.switchCamera();
						this.stop();
						// 被监测到以后 肯定会弹窗的  那么就去开启监测用户是否点击取消的定时器/
						this.qvXiao()
						clearInterval(this.intervalIdIsBeiJieCeLa)
						this.intervalIdIsBeiJieCeLa = null
					}
				}, 1000)
			},
			// 这个qvxiao的名字 有误导  实际上是被监测到后弹窗那个时刻
			qvXiao() {
				console.log("用户点击了取消1")
				let qvXiaoFlag = true
				this.intervalIdIsQvXiao = setInterval(() => {
					console.log("用户点击了取消2")
					// 判断用户是否点击了取消
					// if(uni.getStorageSync("jieCeHouQvXiao") && qvXiaoFlag) {
					if (uni.getStorageSync("jieCeHouQvXiao")) {
						// 这个一定得加 用户点击取消后会播放视频 可上一次的isPusher状态还是true 所以会走start里面的else 即暂停视频
						this.isPusher = !this.isPusher
						console.log("获取到了取消标志")
						clearInterval(this.intervalIdIsQvXiao)
						this.intervalIdIsQvXiao = null
						uni.setStorageSync("jieCeHouQvXiao", false)
						// qvXiaoFlag = false  当时是以为 执行太快  实际上就是 忽略了isPusher的问题 导致出现视频暂停的问题
						// 开流  
						// setTimeout(()=>{
						this.start()
						// },1000)
						// clearInterval(intervalIdIsQvXiao)

					}

					// 判断用户是否点击了确认
					if (uni.getStorageSync("jieCeHouQueRen")) {
						// 这个一定得加 用户点击取消后会播放视频 可上一次的isPusher状态还是true 所以会走start里面的else 即暂停视频
						this.isPusher = !this.isPusher //这里还得加 因为视频的暂停毕竟不是手动暂停的
						// 实际上就应该在最初视频暂停的地方 统一加一句就不用这里也加了
						console.log("获取到了确认标志")
						clearInterval(this.intervalIdIsQvXiao)
						this.intervalIdIsQvXiao = null
						uni.setStorageSync("jieCeHouQueRen", false)
						// qvXiaoFlag = false
						// 开流  
						// setTimeout(()=>{
						// this.start()
						// },1000)
						// clearInterval(intervalIdIsQvXiao)

					}
				}, 1000)
			},
			// 检验流连接是否成功的方法
			streamLinked() {
				console.log("执行了吗 streamLinked()")
				this.intervalId = setInterval(() => {
					uni.request({
						url: pythonUrl + '/video/isOpenVideo',
						method: 'GET' // 明确指定请求方法
					}).then((res) => {

						console.log("嗅探：推流是否成功连接后端")
						if (res.data.data) {
							console.log("推流连接成功")
							// 往本地存储flag1为true

							// 算了  先别执行这下面的  第一次嗅探成功后 只做提示
							// uni.setStorageSync("flag1", true)
							// // this.qvXiao()
							// this.beiJieCeLa()

							clearInterval(this.intervalId);
							this.intervalId = null
							// 成功连接后 再发一个请求 怕第一次的连接是假连接
							uni.request({
								url: pythonUrl + '/video/isOpenVideo',
								method: 'GET' // 明确指定请求方法
							}).then((res) => {
								// 如果这次返回的还是true,那么就肯定说明流流连接成功了 
								if (res.data.data) {
									console.log("第二次验证推流连接确定成功，不是假连接")
									// 确定是真的连接 才进行flag1标志变换为true  并开启beijce的定时器方法
									// 这样相比于在上面直接执行 会慢个2s？(请求的时间)
									uni.setStorageSync("flag1", true)
									// this.qvXiao()
									this.beiJieCeLa()
								} else {
									console.log("第二次检验，推流未连接，需要重新推流，执行streamLinked()方法里定时器")
									streamLinked()
								}
								// 否则就直接重新执行此定时器  
							})
						} else {
							console.log("推流未连接，需要重新推流")
							// 加推流的操作代码  失败后的
							// pause()
							this.stop()
							// 先把上次推出去的流关闭 再重新推
							this.context.start({
								success: (a) => {
									// console.log("livePusher.start:" + JSON.stringify(a));
								}
							})

						}
					})
				}, 5000);
			},
			close() {
				this.context.close({
					success: (a) => {
						console.log("livePusher.close:" + JSON.stringify(a));
					}
				});
			},
			snapshot() {
				this.context.snapshot({
					success: (e) => {
						console.log(JSON.stringify(e));
					}
				});
			},
			resume() {
				this.context.resume({
					success: (a) => {
						console.log("livePusher.resume:" + JSON.stringify(a));
					}
				});
			},
			pause() {
				this.context.pause({
					success: (a) => {
						console.log("livePusher.pause:" + JSON.stringify(a));
					}
				});
			},
			stop() {
				this.context.stop({
					success: (a) => {
						console.log(JSON.stringify(a));
					}
				});
			},
			switchCamera() {
				this.context.switchCamera({
					success: (a) => {
						console.log("livePusher.switchCamera:" + JSON.stringify(a));
					}
				});
			},
			startPreview() {
				this.context.startPreview({
					success: (a) => {
						console.log("livePusher.startPreview:" + JSON.stringify(a));
					}
				});
			},
			stopPreview() {
				this.context.stopPreview({
					success: (a) => {
						console.log("livePusher.stopPreview:" + JSON.stringify(a));
					}
				});
			}
		}
	}
</script>

<script setup>
	import {
		ref,
		nextTick,
		onMounted,
		onBeforeMount
	} from 'vue'
	import {
		statusBarHeight,
		TitleBarHeight
	} from '../../utils/system.js'
	import {
		onReady,
		onLoad,
		onShow
	} from '@dcloudio/uni-app'
	import apis from '../../api/apis.js';
	import {
		get,
		pythonUrl
	} from '../../utils/request.js';
	// import uniSpeech from '@/uni_modules/uni-speech/js_sdk/uni-speech.js'
	const page_gesture = ref(true)
	const show_center_play_btn = ref(false)
	const enable_play_gesture = ref(true)
	const show_mute_btn = ref(true)
	const topBarIndex = ref(0)
	//内容块的高度
	const clentHeight = ref(0)
	let itemName = '.home-data'
	const infopopup = ref(null)
	const answerpopup = ref(null)
	const quickPositionpopup = ref(null)

	const topBar = ref([{
			name: '目录'
		},
		{
			name: '课程简介'
		},
		{
			name: '评论'
		},
		{
			name: '笔记'
		}
	])
	const isJoined = ref(false)


	function getHomeDataHeight() {


		const view = uni.createSelectorQuery().select(itemName).boundingClientRect((data) => {
				clentHeight.value = data.height
				console.log(itemName)
			})
			.exec();
	};
	// 初始化时获取数据
	onReady(() => {
		// changeTab(topBar.value[0]?.id, 0); // 使用可选链操作符确保安全访问
		// 延迟获取内容块的高度
		// onNavigationBarButtonTap()
		nextTick(() => {
			setTimeout(() => {
				getHomeDataHeight();
			}, 200); // 等待 DOM 完全渲染完成
		});
	});

	function changeTab(index) {
		// test()
		if (topBarIndex.value === index) {
			return;
		}
		topBarIndex.value = index;
		scrollIntoIndex.value = "top" + index
		// this.swiperCurrent = index
		// console.log(index)
		switch (index) {
			case 0:
				itemName = '.home-data'
				// console.log(this.itemName)
				break;
			case 1:
				itemName = '.course-data'
				break;
			case 2:
				itemName = '.remark-data'
				break;
			case 3:
				itemName = '.note-data'
				break;
		}
		getHomeDataHeight()
	}

	const onChangeTab = (e) => {
		changeTab(e.detail.current)
	}
	const courseList = ref([])
	//添加课程
	const getUserCourseList = async () => {
		let res = await apis.getUserCourse()
		// console.log(res.data)
		courseList.value = res.data
		// console.log(courseList.value.find(item => item['courseId'] == courseId.value))
		courseList.value.find(item => item['courseId'] == courseId.value) ? isJoined.value = true : isJoined
			.value = false

	}

	const getUserLike = () => {
		apis.saveUserLike(courseId.value).then(res => {
			if (res.data === true) {
				isJoined.value = true
				uni.showToast({
					title: '添加成功！',
					icon: 'none'
				});
			} else
				isJoined.value = false
		}).catch(err => {
			uni.showToast({
				title: '添加失败！',
				icon: 'none'
			});
		})
	}

	const scrollIntoIndex = ref("top0")
	const courseId = ref(0);
	// 获取url中的课程id
	onLoad((e) => {
		console.log("课程id");
		console.log(e);
		loadChapter(e.id);
		courseId.value = e.id
		uni.setNavigationBarTitle({
			title: e.name
		})
		getUserCourseList()

	})
	//关闭拉框
	const closer = () => {
		infopopup.value.close()
		answerpopup.value.close()
		quickPositionpopup.value.close()
		// 关闭课程问答的标志
		isCourseAsk.value = false;
	}
	//课程问答框
	const isCourseAsk = ref(false)
	const onAskAnswer = () => {
		answerpopup.value.open()
		isCourseAsk.value = true
	}


	const onQuickPosition = () => {
		isPosition.value = false
		quickPositionpopup.value.open()
		// isCourseAsk.value = true
	}
	//视频总结框
	const onSummary = () => {
		infopopup.value.open()
	}
	//智能助手跳转，有问题
	const onAIOpen = () => {
		uni.navigateTo({
			url: '/pages/assistant/assistant'
		})
	}
	// 定义一个视频src变量
	const videoUrl = ref("");
	// 获取课程章节信息
	const chapterArr = ref([]);
	const chapter = ref({});
	// 课程介绍
	const courseIntroduceInfo = ref({})

	const loadChapter = (courseId) => {
		// 这个是暂时用的
		// apis.getChapterName(courseId).then((res) => {

		// 这个是等后端打包更新数据以后 改回来
		apis.getCourseCatalog(courseId).then((res) => {
			chapterArr.value = res.data
			// console.log(chapterArr.value)

			// 开始请求上次看到了那个视频（给后端传courseId）   点击某个视频的时候就要把该视频id传回去 表示我currentChapter是xxx
			// 如果某个课程用户是没有看过的 那么正常是自动播放第一个视频（也就是后端给我传一个默认值 如0 那么我就知道要播放第一个视频，即获取数组的第一个元素）  如果用户有看过的  那么就自动播放上次看到那个视频）
			//  通过视频id去获取对应的评论  笔记等其他数据

			// 拿到上次看的视频  没有就默认取第一个视频
			apis.getLastVideo(courseId).then((res) => {
				// 由于以上返回的都是章节信息,所以课程简介需要单独再发送请求  屎
				apis.getSingleCourseIntroduce(courseId).then((res) => {
					// console.log("获取单个课程信息")
					// console.log(res.data)
					courseIntroduceInfo.value = res.data
					// console.log("课程介绍")
					// console.log(courseIntroduceInfo.classHour)
				})
				if (res.data === 0) {
					// playChapter(chapterArr.value[0].courseResourceId)
					// loadChapterComments(chapterArr.value[0].courseResourceId)
					// loadChapterNotes(chapterArr.value[0].courseResourceId)
					// loadChapterHomework(chapterArr.value[0].courseResourceId)
					// 把视频总结放到了视频播放哪里 所以这里就不用请求了
					// loadChapterVideoSummary()


					// 加载ai字幕  一样放到了playChapter里面  方便章节切换
					// loadVideoSubtitle(chapterArr.value[0].courseResourceId)
				} else {
					chapter.value = res.data
					videoUrl.value = chapter.value.videoUrl
					// 指定视频进度开始位置
					initialTime.value = chapter.value.allViewTime
					// 确保用户在视频未播放时,点击课程问答,AIJieDa会有值
					AIJieDa.value = initialTime.value
					// console.log(chapter.value.videoUrl)
					lastRecordTime.value = initialTime.value
					// console.log(videoUrl.value)
					// options.src = chapter.value.videoUrl //这里的属性没有统一 那个手动点击的 是给url  这里是给videoUrl  应该不影响
					// options2.src = chapter.value
					// 	.videoUrl //这里的属性没有统一 那个手动点击的 是给url  这里是给videoUrl  应该不影响
					// videoLoaded.value = true
					// aizmFalg.value = true
					loadChapterComments(chapter.value.courseResourceId)
					loadChapterNotes(chapter.value.courseResourceId)
					// loadChapterHomework(chapter.value.courseResourceId)
					// loadChapterVideoSummary(chapter.value.videoUrl)  换成python了，这里的java的不用了
					loadChapterVideoSummary(chapter.value.courseResourceId)
					// 加载ai字幕
					// loadVideoSubtitle(chapter.value.courseResourceId)
					// 加载思维导图
					// loadChapterMindmap(chapter.value.videoUrl)
				}
				// 一进入页面就默认选择评论进行加载
				// handleMenuSelect('comment')
			})


		})



	}

	// 选择单个章节
	const selectSidebar = (index) => {
		playChapter(index)
		// loadChapterVideoSummary()
		// loadChapterComments(index)
		// loadChapterNotes(index)
		// loadChapterHomework(index)
	}

	// 通过点击章节把章节id传给后端   获取视频数据的
	const playChapter = (resourceidId) => {
		apis.getSingleChapterInfo(resourceidId).then((res) => {
			chapter.value = res.data
			videoUrl.value = chapter.value.url
			// console.log(videoUrl.value)
			// options.src = chapter.value.url
			// options2.src = chapter.value.url
			// 这个变量 方便没有用了  草
			// videoLoaded.value = true
			// 视频加载完成 显示ai字幕
			// aizmFalg.value = true


			// loadChapterVideoSummary(chapter.value.url)
			// loadVideoSubtitle(resourceidId)
			// 加载思维导图数据
			// loadChapterMindmap(chapter.value.url)


			// console.log(chapter.value)
		})
	}

	// 加载评论
	const aijx = ref('')
	const commentArr = ref([{
		picUrl: '',
		context: '',
		createrId: 0,
		userName: '',
		updateTime: ''
	}])
	const loadChapterComments = (courseResourceId) => {
		apis.loadChapterComment(courseResourceId).then((res) => {
			apis.getCommentSummary(courseResourceId).then((res) => {
				aijx.value = res.data
			})
			commentArr.value = res.data
			// console.log("评论内容")
			// console.log(commentArr.value)
		})
	}

	//评论部分
	const remarks = ref([])
	const aremark = ref('')
	const remarkInput = (e) => {
		aremark.value = e.detail.value

		// console.log(aremark.value)
	}
	const onSend = () => {
		if (aremark.value.trim()) {
			remarks.value.push(aremark.value)
			aremark.value = ''
		}
		console.log(remarks.value)
	}



	// const videoComment = async () => {
	// 	let res = await apis.getCommentSummary(id.value)
	// 	console.log(res)
	// }
	// videoComment()

	// 用户评论的内容
	const comment = ref('')
	// 发布评论
	const post = () => {
		// let userInfo = localStorage.user ? JSON.parse(localStorage.userInfo) : null;

		if (comment.value?.trim() === '') {
			// ElMessage.error('请输入讨论内容!')
			uni.showToast({
				title: '请输入讨论内容',
				duration: 2000,
				icon: "none"
			});

			return
		}
		// comment.value.userId = userInfo.id

		//  发布讨论内容    给后端传过去  紧接着调用loadComments  下面的资源id得让后端统一一个名字 不然前端这里就没法弄 前端只能用一个名字
		apis
			.postChapterComment(courseId.value, chapter.value.courseResourceId, comment.value)
			.then((res) => {
				if (res.data === '发布内容违规') {
					// ElMessage.error('发布内容违规')
					uni.showToast({
						title: '发布内容违规',
						duration: 2000,
						icon: "none"
					});
					comment.value = ''

					return
				} else {
					uni.showToast({
						title: '发布成功',
						duration: 2000,
						icon: "none"
					});
				}
				// ElMessage.success('发布成功')

				comment.value = ''

				// aijxShow.value = true

				loadChapterComments(chapter.value.courseResourceId)
			})
	}


	//笔记
	const note = ref({
		courseResourceId: '',
		docTitle: '',
		docSummary: '',
		docContext: ''
	})
	// 用户章节笔记
	const loadChapterNotes = (courseResourceId) => {
		// 获取后端传来的笔记列表
		apis.getChapterNote(courseResourceId).then((res) => {
			// 加判断 避免返回null 的情况  这里后端没有数据，直接不返回data字段
			if (!res.data) return
			note.value = res.data
			// console.log("笔记")
			// console.log(note.value)
			// editor.txt.html(note.value.docContext)
			// 设置笔记内容,让笔记内容可以回显
			setEditorContent()
		})
	}



	// 视频总结
	const videoSummary = ref()
	const videoSummaryFlag = ref(false)
	const loadChapterVideoSummary = (courseResourceId) => {
		// api.getVideoSummary(chapter.value.videoUrl, 'null').then((res) => {
		// apis.getVideoSummary(videoUrl, 'null').then((res) => {
		// 	// console.log(res)
		// 	videoSummary.value = res.data
		// 	// initValue.value = res.data.data
		// })
		console.log("视频总结开始")
		uni.request({
			url: pythonUrl + '/video/videoContent?courseResourceId=' + courseResourceId + '&flag=0',
			method: 'GET' // 明确指定请求方法
		}).then((res) => {
			videoSummary.value = res.data.data
			console.log("视频总结的内容：", res.data.data)
			videoSummaryFlag.value = true
		})
	}

	// 保存笔记
	const save = () => {
		console.log(note.value)
		// 获取编辑器结点
		getEditorContent()
		// if (note.value.docTitle.trim() == '') { ElMessage.error('请输入标题!'); return; }
		// if (note.value.text.trim() === '') { ElMessage.error('请输入笔记内容!'); return; }
		//从富文本编辑器中获取文章内容与摘要
		// note.value.docContext = editor.txt.html()
		// note.value.docSummary = editor.txt.text().slice(0, 30);
		// 这里先不要考虑 点击进入课程 自动定位到上一个视频的问题  还有那个第一次进入该课程默认选择第一章节（视频）问题
		// 我把默认选择chapterArr.value[0]里的id给到chapter即可
		note.value.courseResourceId = chapter.value.courseResourceId
		// let data = qs.stringify(content.value)  这里看用不用转  不用直接给note.value
		apis.saveChapterNote(note.value).then(() => {
			// ElMessage.success('保存成功')
			uni.showToast({
				title: "笔记保存成功"
			})
		})
	}



	// 笔记润色
	const polish = () => {
		uni.showToast({
			title: "AI正在为您润色，请稍后...",
			icon: "none"
		})
		// 这个必须得加 因为当editor进行了编辑，docContext没法动态更新
		getEditorContent()
		apis
			.getNoteCorrection(
				note.value.docTitle,
				note.value.docSummary,
				note.value.docContext,
				note.value.courseResourceId
			)
			.then((res) => {
				uni.showToast({
					title: "AI润色完毕",
					icon: "none"
				})
				note.value.docTitle = res.data.title
				note.value.docSummary = res.data.sumUp
				note.value.docContext = res.data.text
				// 设置笔记内容,让笔记内容可以回显
				setEditorContent()
				// editor.txt.html(note.value.docContext)
			})
	}

	// 笔记纠错
	const msgType = ref("")
	const alertDialog = ref()
	// const isJiuCuo = ref(false)
	const aiJCContent = ref("")
	// 用户点击确定执行
	const dialogConfirm = () => {
		// isJiuCuo.value = true
		note.value.docTitle = note2.value.docTitle
		note.value.docSummary = note2.value.docSummary
		note.value.docContext = note2.value.docContext
	}
	// 不走上面的,那么默认就是false,不用写下面方法
	// const dialogClose = ()=>{
	// 	isJiuCuo.value = false
	// }
	// 定义note副本 用来处理用户取消纠错的问题
	const note2 = ref({})
	const correct = () => {
		uni.showToast({
			title: "AI正在为您纠错，请稍后...",
			icon: "none"
		})
		let editorCtx;
		getEditorContent()


		// msgType.value = "center"
		// alertDialog.value.open()
		// console.log("未纠错")
		// if (!isJiuCuo.value) return
		// console.log("已纠错")
		apis
			.getNoteErrorCorrection(
				note.value.docTitle,
				note.value.docSummary,
				note.value.docContext
				// editor.txt.text()
			)
			.then((res) => {
				// 专门弹出对话框来告诉用户纠了哪些错!
				// aijiuCuo.value = true
				// aijcText.value = res.data.data.prompt

				// 获取到纠错的错误
				aiJCContent.value = res.data.prompt
				msgType.value = "center"
				alertDialog.value.open()
				// console("未纠错")
				// if (!isJiuCuo.value) return  没法用 不会等你在对话框选择后再执行
				// console("已纠错")
				// 以下的 直接就继续执行了  所以要定义副本 然后在对应确认方法里正式赋值给note
				note2.value.docTitle = res.data.title
				note2.value.docSummary = res.data.sumUp
				note2.value.docContext = res.data.text
				// 设置笔记内容,让笔记内容可以回显
				setEditorContent()
			})
	}

	// 课程问答
	const AIJieDa = ref(0) //用来给后端传递当前视频播放的时间点
	const question = ref("") //接收用户输入的问题
	const courseAskAnswer = ref()
	const aiStartInitiative = () => {
		console.log("发送课程问答请求")
		// ElMessage.success('AI正在分析中...请稍后')
		// 调接口
		// apis
		// 	.getVideoAnswer(chapter.value.courseResourceId, question.value, AIJieDa.value)
		// 	.then((res) => {
		// 		courseAskAnswer.value = res.data.text
		// 		console.log("课程问答的回复：", courseAskAnswer.value)
		// 		// AIText.value = res.data.data.text
		// 		// drawer.value = true
		// 		// analyse.value = false
		// 	})
		// 响应成功 完    analyse.value = false
		// dialogVisible.value = false
		uni.request({
			url: pythonUrl + '/video/knowledgeBaseQuestionAnswering?courseResourceId=' + chapter.value
				.courseResourceId + '&question=' + question.value,
			method: 'GET', // 明确指定请求方法
			timeout: 60000
		}).then((res) => {
			// console.log("课程问答的回复：", res.data.data)
			courseAskAnswer.value = res.data.data
			console.log("课程问答的回复：", res.data.data)
		})
	}

	// 快速定位
	const position = ref("")
	// const positionTimePoint = ref([1.07,300.08,1000.07])  小数 app中不给你跳转
	const positionTimePoint = ref([1, 300, 1000]) //只能是整数
	const isPosition = ref(false)
	const totalLength = ref(0)

	const preOrNext = (e) => {
		console.log("上一页或下一页", e)
		// let i = e.current
		// i = 当前页码 / 10  不对 这里不用除
		// 直接弄成 如arr[i] 
		console.log("positionTime：" + positionTimePoint.value[e.current - 1])
		videoContext.seek(positionTimePoint.value[e.current - 1])
		// console.log()
		// console.log("初始值：", initialTime.value)
	}

	const quickPositionMethod = () => {
		console.log("发送定位请求")
		//发送视频内容关键字to后端  
		// 这里是给python后端发送的
		uni.request({
			url: pythonUrl + '/video/retrieving_chat_videos?courseResourceId=' + chapter.value
				.courseResourceId + '&question=' + position.value,
			method: 'GET' // 明确指定请求方法
		}).then((res) => {
			// console.log(res.data)
			// positionTimePoint.value = res.data.data  
			positionTimePoint.value = res.data.data.map(time => Math.floor(time)) //向下取整，舍弃小数部分。

			console.log(positionTimePoint.value)
			// console.log(positionTimePoint.value.length)
			totalLength.value = positionTimePoint.value.length * 10
			// console.log("total长度："+totalLength.value)

			videoContext.seek(positionTimePoint.value[0])
			// 将发送按钮变换为箭头
			isPosition.value = true
		})
		// 后端返回数组后,如果数组长度不为0 则乘以10 给到total,因为满10条数据为一页
		// 而这里要实现的是,数组长度是几,就是几页
		// 如果==0 ,则提示未找到相关内容 return

		// 要把后端返回的数组第一个下标对应的值先赋值给videoContext




	}

	// 定义用户观看的行为变量
	const userAction = ref({})

	let pusherInterValIdVue3 = null

	// 定时发送请求给后端,获取用户观看状态（前提推流开启）
	const getUserAction = (time) => {
		// console.log("推流前发送请求")
		console.log("发送推流响应的请求")
		// 什么时候清空这个定时器 ？ 视频暂停或ai伴学关闭
		pusherInterValIdVue3 = setInterval(() => {
			uni.request({
				url: pythonUrl + '/video/getUsrActions?nowViewTime=' + time + '&courseResourceId=' +
					chapter.value.courseResourceId,
				method: 'GET' // 明确指定请求方法
			}).then((res) => {
				console.log("成功响应用户观看时的行为：", JSON.stringify(res.data.data))
				userAction.value = res.data.data



				// 疲劳监测   
				if (res.data.data.actions.includes('yawn') || res.data.data.actions.includes(
						'tried')) {
					loadPiLao()
				}

				// 困惑监测
				if (res.data.data.actions.includes('scratch_head') || res.data.data.actions.includes(
						'frown')) {
					kunHuo()
				}

				// 走神监测   
				if (res.data.data.actions.includes('phone')) {
					zoushen()
				}

				// 人离开监测  
				if (res.data.data.pause == false) {
					liKai()
				}
			})
		}, 5000)

	}

	const videoContext = uni.createVideoContext('myVideo')


	// 点击箭头的事件

	// 一直点,一直往后寻找视频内容（更新视频时间点）,直到数组遍历到末尾 即=其长度 终止

	// 终止后 要提示 没有更多了... 
	// 正常是还能往后点


	// 添加监测变量和方法
	// 1.疲劳监测 = ref()
	const alertDialogPiLao = ref()
	const pLJCContent = ref("")
	const dialogConfirmPL = () => {
		// 确认休息
		// 把红色按钮隐藏
		// isSmartMonitor.value = false  不能隐藏草 否则影响

		// 用户点击确认后 那么需要把之前vue2中的intervalIdIsQvXiao定时器清除
		// 之前是用户点击取消事件的清除方式
		// 所以现在确认这里也需要一个标志
		uni.setStorageSync("jieCeHouQueRen", true)

	}


	const dialogClosePL = () => {
		// 继续学习
		// 存这个 目的是 为了vue2中可以通过此变量 重新推流
		uni.setStorageSync("jieCeHouQvXiao", true)
		// videoContext.play()
		// 让vue2中 通过这个标识来执行是否重新建立推流的连接
		// 这个属于用户没有手动点击视频的播放按钮的红色键
		// 只要一疲劳或其他监测到,就直接执行下面这句 放这里太晚了
		// 目的就是等到弹出的提示里执行视频暂停时,vue2中可以获取到该标志false
		// 继而执行停流操作
		// uni.setStorageSync("flag1", false)  
		// 视频一播放就触发那边的播放事件  
		// alertDialogPiLao.value.open()


	}

	// 疲劳监测
	const loadPiLao = () => {
		uni.setStorageSync("flag1", false)
		videoContext.pause()
		// 本来应该往这里加一句 this.isPusher = !this.isPusher;  但是isPusher是vue2中
		// 所以只能麻烦在vue2中多次加这一句判断了 
		// 弹出提示  
		setTimeout(() => {
			pLJCContent.value = "监测到您多次闭眼或打哈欠，建议您休息一下哦";
			alertDialogPiLao.value.open()
		}, 1000)
	}


	// 困惑监测
	const kunHuo = () => {
		uni.setStorageSync("flag1", false)
		videoContext.pause()
		// 本来应该往这里加一句 this.isPusher = !this.isPusher;  但是isPusher是vue2中
		// 所以只能麻烦在vue2中多次加这一句判断了 
		// 弹出提示  
		setTimeout(() => {
			// 得特殊处理了
			pLJCContent.value = "监测到您多次皱眉或挠头，是否需要AI为您分析当前位置的疑惑？";
			alertDialogPiLao.value.open()
		}, 1000)
	}

	// 走神监测
	const zoushen = () => {
		uni.setStorageSync("flag1", false)
		videoContext.pause()
		// 本来应该往这里加一句 this.isPusher = !this.isPusher;  但是isPusher是vue2中
		// 所以只能麻烦在vue2中多次加这一句判断了 
		// 弹出提示  
		setTimeout(() => {
			pLJCContent.value = "监测到您已走神，为您自动暂停视频";
			alertDialogPiLao.value.open()
		}, 1000)
	}

	// 人离开监测
	const liKai = () => {
		uni.setStorageSync("flag1", false)
		videoContext.pause()
		// 本来应该往这里加一句 this.isPusher = !this.isPusher;  但是isPusher是vue2中
		// 所以只能麻烦在vue2中多次加这一句判断了 
		// 弹出提示  
		setTimeout(() => {
			pLJCContent.value = "监测到您已离开，为您自动暂停视频";
			alertDialogPiLao.value.open()
		}, 1000)
	}





	// 添加监测变量和方法


	// const checkList =  [false, false, false, false, false, false]
	// 定义收藏状态数组
	const checkList = ref([false, false, false, false, false]);
	const contentText = ref({
		contentDefault: 'AI伴学',
		contentFav: 'AI伴学'
	})
	// 点击事件处理函数
	const favClick = (index) => {
		checkList.value[index] = !checkList.value[index];
		console.log(`收藏状态改变，当前状态: ${checkList.value[index]}`);
	};

	// 视频初始化时,进度定位的位置
	const initialTime = ref(0)
	// 当前视频进度位置 确保定时给后端返回视频进度位置
	const currentTime = ref(0)
	// 上次的视频进度
	const lastRecordTime = ref(0)
	const elapsedTime = ref(0);

	// 定义一个推流前成功发送请求的标志，用来在vue3中定时发送请求
	const sendRequest = ref(false)

	// 视频播放时,会一直记录视频播放进度
	const timeupdate = (event) => {
		// console.log("视频更新时间")
		// console.log(event.detail)
		// 当点击课程问答后,才允许当前视频的时间点赋值
		// 担心的是,如果视频是先暂停,再点击课程问答,那么应该就出问题了
		// 要么直接就是 不加这个判断了
		// 解决:给一个初始值为0,如果是有上次看到的进度,那么视频加载时,会拿到上次进度给到AIJieDa




		currentTime.value = event.detail.currentTime
		elapsedTime.value = currentTime.value - lastRecordTime.value
		// console.log("上次：", lastRecordTime.value)
		// console.log("ela:", elapsedTime.value)
		// console.log("elapsedTime")
		// console.log(elapsedTime)
		// 每隔10s发送一次 视频进度给后端


		// 如果第一个推流前的状态已发送,那么才开始走这个请求

		// 要保证是推流开启的状态  并且 要第一次定时 4s后 改一个flag 之后继续定时发送请求
		// 如果 推流 关闭 那么这个flag就归位
		// 如果用户直接退出页面  应该不用考虑 会重新加载页面
		// if (isSmartMonitor.value && !sendRequest.value) {
		// 	setTimeout(() => {
		// 		sendRequest.value = true
		// 	}, 4000)
		// }
		// if (sendRequest.value) {
		// 	console.log("vue3处开始发送请求")
		// 	setTimeout(() => {
		// 		getUserAction()
		// 	}, 3000)
		// }

		if (elapsedTime.value >= 3) {
			// 记录的api  把课程id  章节id  最后一次观看时间 传过去
			apis
				.recordHistory(
					courseId.value,
					chapter.value.courseResourceId,
					event.detail.currentTime
				)
				.then((res) => {
					console.log("记录进度")
					// 判断返回的data是否存在？
					// 否:return
					// 是:继续判断监测到的什么行为 
					// 疲劳:打哈欠 打盹 则进行相应提示；
					// 暂停视频播放

					// videoContext.pause()
					// // 弹出提示  
					// setTimeout(()=>{
					//  alertDialogPiLao.value.open()
					// },1000)

					// 用户点击确认 进行休息 
					// 用户点击取消  则继续播放视频

					// 困惑:.....



					// console.log(res)
					// 避免为空   返回时  每次返回一道题目 和对应一道解析
					// if (res.data) {
					//   huDong.value = res.data.data
					//   // 触发互动对话框
					//   huDongShow.value = true
					//   // 问题出现后  视频如果是播放状态 那么就给暂停
					//   if (isPlaying.value) {
					//     videoPlayer.value.pause()
					//   }

					// }
				})
			// time.value = 0
			lastRecordTime.value = currentTime.value // 更新lastRecordTime为当前时间
		}


		if (isCourseAsk.value) {
			AIJieDa.value = event.detail.currentTime
			// console.log("课程播放时间点",AIJieDa.value)
		}

	}

	// 获取富文本编辑的内容方法
	const getEditorContent = () => {
		uni.createSelectorQuery().select('#editor').context((res) => {
			let editorCtx = res.context;
			// console.log(editorCtx)
			// 获取编辑的内容   html格式或text都有
			editorCtx.getContents({
				success: function(A) {
					// console.log("文本详情：", A)
					// console.log("html：", A.html)
					note.value.docContext = A.html
				},
				fail: function(A) {}
			})
		}).exec()
	}
	// 设置富文本编辑的内容
	const setEditorContent = () => {
		uni.createSelectorQuery().select('#editor').context((res) => {
			let editorCtx = res.context;
			// console.log(editorCtx)
			// 获取编辑的内容   html格式或text都有
			editorCtx.setContents({
				html: note.value.docContext,
				success: () => {
					console.log("设置内容成功");
				},
				fail: (A) => {
					console.error("设置内容失败：", A);
				}
			})
		}).exec()
	}
	//添加课程



	//富文本组件JS

	// 数据
	const readOnly = ref(false);
	const formats = ref({});

	// 方法
	const format = (e) => {
		const {
			name,
			value
		} = e.target.dataset;
		if (!name) return;
		editorCtx.value.format(name, value);
	};

	const onStatusChange = (e) => {
		const formatsValue = e.detail;
		formats.value = formatsValue;
	};

	const onEditorReady = () => {
		if (process.env.VUE_APP_PLATFORM === 'MP-BAIDU') {
			const editorLib = requireDynamicLib('editorLib');
			editorCtx.value = editorLib.createEditorContext('editor');
		} else {
			uni.createSelectorQuery().select('#editor').context((res) => {
				editorCtx.value = res.context;
			}).exec();
		}
	};

	const undo = () => {
		editorCtx.value.undo();
	};

	const redo = () => {
		editorCtx.value.redo();
	};

	const insertDivider = () => {
		editorCtx.value.insertDivider({
			success: () => {
				console.log('insert divider success');
			}
		});
	};

	const clear = () => {
		uni.showModal({
			title: '清空编辑器',
			content: '确定清空编辑器全部内容？',
			success: (res) => {
				if (res.confirm) {
					editorCtx.value.clear({
						success: () => {
							console.log('clear success');
						}
					});
				}
			}
		});
	};

	const removeFormat = () => {
		editorCtx.value.removeFormat();
	};

	const insertDate = () => {
		const date = new Date();
		const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
		editorCtx.value.insertText({
			text: formatDate
		});
	};

	const insertImage = () => {
		uni.chooseImage({
			count: 1,
			success: (res) => {
				editorCtx.value.insertImage({
					src: res.tempFilePaths[0],
					alt: '图像',
					success: () => {
						console.log('insert image success');
					}
				});
			}
		});
	};


	// 编辑器上下文
	const editorCtx = ref(null);

	// 监控 
	// 传递是否监测的布尔值
	// const isMonitorBoolean = ref(true)
	// 是否开启智能监测
	const isSmartMonitor = ref(false)
	const isSmartMonitorMethod = () => {
		isSmartMonitor.value = !isSmartMonitor.value
		if (!isSmartMonitor.value && pusherInterValIdVue3 != null) { //关闭ai伴学  
			// 要考虑到如果用户光直接开启和关闭ai伴学 并没有播放视频 进行推流  那你这里必须多一个推流响应定时器是否不为null的判断
			// 这里默认 推流响应请求执行 == 用户肯定进行了推流
			// 清空推流的响应请求的定时器
			console.log("关闭推流响应的请求定时器")
			clearInterval(pusherInterValIdVue3)
			pusherInterValIdVue3 = null
		}
	}
	// 执行子组件方法
	// 推流开始  执行不了
	// const liveStart = () => {
	// 	if (liveObject.value) {
	// 		liveObject.value.start()
	// 	}
	// }
	// // 推流关闭
	// const liveStop = () => {
	// 	if (liveObject.value) {
	// 		liveObject.value.stop()
	// 	}
	// }
	// 监控  	
	const test = () => {
		// 开启监控(注意不是推流哦)
		isSmartMonitor.value = !isSmartMonitor.value
		// uni.navigateTo({
		// 	url:"/pages/test2/test2"
		// })
	}

	// 封装一个定时执行推流响应请求任务的方法
	// getUserAction 不用了  有这个


	// 视频播放 
	// 点击播放 如果已开启监控,那么就触发推流和切换摄像头的方法

	// 这个定时器是确认推流成功连接后 才停止执行
	let PusherLinkedIntervaIdVue3 = null;
	const play = () => {
		console.log("播放")
		// loadPiLao()
		// 清空上一次的定时器
		if (PusherLinkedIntervaIdVue3 != null) {
			clearInterval(PusherLinkedIntervaIdVue3)
		}
		// 直接定时执行  直到成功拿到true才停 
		// 前提是ai伴学开启后 才执行定时器
		if (isSmartMonitor.value) {
			PusherLinkedIntervaIdVue3 = setInterval(() => {
				// flag1这里就是为了确保建立推流连接 
				let flag = uni.getStorageSync("flag1")
				console.log("flag1：", flag)
				if (flag) {
					getUserAction(currentTime.value)
					clearInterval(PusherLinkedIntervaIdVue3)
					PusherLinkedIntervaIdVue3 = null
					console.log("清空推流连接的嗅探请求定时器")


				}
			}, 1000)
		}




		// 之后发推流响应的请求

		// load()
		// 触发推流  
		// 大意了  这里调用不了start,因为start是在另一script里写的方法
		// if (isSmartMonitor.value) start()
	}

	// 视频暂停
	// 点击暂停 如果已开启监控,那么就触发停止推流的方法
	const pause = () => {
		console.log("暂停")
		console.log("pusherInterValIdVue3:", pusherInterValIdVue3)
		if (pusherInterValIdVue3 != null) {
			clearInterval(pusherInterValIdVue3)
			pusherInterValIdVue3 = null
			console.log("清空推流响应的请求定时器")
		}
	}

	// 视频到末尾后  再说吧
	const ended = () => {
		console.log("末尾")
	}
	// 监控

	// 生命周期钩子
	onBeforeMount(() => {
		// #ifndef MP-BAIDU
		uni.loadFontFace({
			family: 'Pacifico',
			source: 'url("https://sungd.github.io/Pacifico.ttf")'
		});
		// #endif
	});


	onShow(() => {
		// uni.setStorageSync("jieCeHouQvXiao",true)
		uni.setStorageSync("flag1", false) //确认推流连接成功后不再发送嗅探请求
		// 用户点击监测后的确认 初始值
		uni.setStorageSync("jieCeHouQueRen", false)
		// 用户点击监测后的取消 初始值
		uni.setStorageSync("jieCeHouQvXiao", false)
	})

	onMounted(onEditorReady);
</script>

<style lang="scss" scoped>
	@import url("../../commons/styles/editor-icon.css");

	.livePusher {
		width: 10rpx;
		height: 10rpx;
		// display: none;
		opacity: 0;
		background-color: #eee;

	}

	.selected {
		color: #06c;
	}

	// .btn{
	// 	width: 24rpx;
	// 	position: fixed;
	// 	top: 280rpx;
	// 	left: 16rpx;
	// 	height: 24rpx;
	// 	// z-index:999
	// 	// opacity: 0.5;
	// }

	.favBtn {
		position: fixed;
		top: 450rpx;
		font-size: 38rpx;
		width: 160rpx;
		height: 80rpx;
	}

	.container {
		width: 100vw;
		// height: 100vh;

	}

	.overlay {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
	}

	.video {
		width: 100vw;
		height: 30vh;

		// position: fixed;
		// z-index: 0;
	}

	video {

		width: 100%;
		height: 100%;
		// position: fixed;
	}

	.scroll-content {
		margin-top: 30rpx;
		width: 100%;
		height: 80rpx;
		white-space: nowrap;
	}

	.scroll-item {
		display: inline-block;
		padding: 10rpx 30rpx;
		font-size: 32rpx;
	}

	.f-active-color {
		padding: 10rpx 0;
		border-bottom: 6rpx solid #49BDFB;
		color: #49BDFB;
	}

	.f-color {
		color: #636263;
	}

	.title {
		padding: 30rpx 0rpx;
		margin: 0rpx 30rpx;
		background-color: white;
		margin-top: 10rpx;
		border-bottom: 1rpx solid #f1f1f1;

	}

	.title view:nth-of-type(1) {
		font-size: 40rpx;
		font-weight: bold;
		margin-bottom: 20rpx;
	}

	.title view:nth-of-type(2) {
		font-size: 28rpx;
		color: #808080;
	}

	.title view:nth-of-type(2) text {
		margin: 0rpx 10rpx 0rpx 20rpx;
		display: inline-block;
		margin-top: 10rpx;
	}

	.lessons {
		padding: 30rpx;
		margin: 0 auto;
	}

	.lessons_title {
		font-size: 33rpx;
		font-weight: 700;
		padding: 20rpx 0rpx;
	}

	.lessons_content {
		font-size: 30rpx;
		color: #444444;
	}

	.lessons_content view {
		padding: 10rpx 0rpx;
	}

	.icon-daima {
		margin: 0rpx 20rpx;
	}

	.answerpop {
		background-color: #fff;
		padding: 30rpx;
		border-radius: 30rpx 30rpx 0 0;
		overflow: hidden;

		.header {
			display: flex;
			justify-content: space-between;
			align-items: center;

			.title {
				color: black;
				font-size: 30rpx;
				font-weight: 600;
				// padding-left: 6rpx;
			}

			.close {
				padding: 6rpx;
			}
		}


		.ask {
			// position: fixed;
			// position: absolute;
			display: flex;
			justify-content: space-between;
			align-items: center;
			margin-bottom: 10rpx;

			input {
				border: 1rpx solid #636263;
				width: 70%;
				padding: 10rpx;
			}

			button {
				background-color: #33A3DC;
				color: white;
			}
		}

		scroll-view {
			max-height: 45vh;

			.content {
				// display: flex;
				padding: 16rpx 0;
				font-size: 32rpx;
				line-height: 1.7em;

			}
		}
	}

	.infopop {
		background-color: #fff;
		padding: 0 10rpx;
		border-radius: 30rpx 30rpx 0 0;
		overflow: hidden;

		.header {
			display: flex;
			justify-content: space-between;
			align-items: center;

			.title {
				color: black;
				font-size: 30rpx;
				font-weight: 600;
				// padding-left: 6rpx;
			}

			.close {
				padding: 6rpx;
			}
		}

		.lessons_title {
			font-size: 33rpx;
			font-weight: 700;
			padding: 20rpx 0rpx;
		}

		scroll-view {
			max-height: 50vh;

			.content {
				// display: flex;
				padding: 16rpx 0;
				font-size: 32rpx;
				line-height: 1.7em;

				.ask {
					display: flex;
					justify-content: space-between;
					align-items: center;
					margin-bottom: 10rpx;

					input {
						border: 1rpx solid #636263;
						width: 70%;
						padding: 10rpx;
					}

					button {
						background-color: #33A3DC;
						color: white;
					}
				}
			}
		}
	}

	/* 尾部 */
	.bottom {
		border-top: 2rpx solid #CCCCCC;
		background: #f5f5f5;
		display: flex;
		padding: 10rpx;
		// padding-bottom: 50rpx;
		align-items: center;

		// position: fixed;
		bottom: 0;
		z-index: 99;
		width: 100%;
	}

	.bottom-input {
		flex: 1;
		font-size: 35rpx;
		border-radius: 10rpx;
		background: #FFFFFF;
		padding: 17rpx;

	}

	.bottom-button {
		width: 190rpx;
		height: 80rpx;
		font-size: 14px;
		line-height: 80rpx;
		margin-left: 20rpx;
		background: #4A90E2 !important;
	}

	.remarkarea {
		.title {
			font-size: 35rpx;
			font-weight: 600;
		}

		.remarkcontent {

			.hasContant {

				padding: 30rpx;
				border-bottom: 1rpx solid #CCCCCC;
				display: flex;
				// justify-content: space-evenly;
				position: relative;

				.left {
					border: 5rpx solid #33A3DC;
					border-radius: 100rpx;
					width: 15%;
					height: 100rpx;

					top: 0;
					left: 0;

					image {
						// position: absolute;
						width: 100%;
						height: 100%;
						border-radius: 100rpx;
					}
				}

				.right {
					margin-left: 20rpx;
					display: flex;
					align-items: center;
					width: 80%;

					.remark {
						font-size: 25rpx;

					}
				}
			}

		}
	}

	// 富文本
	.noteTitle {
		.title {
			font-size: 35rpx;
			font-weight: 600;
		}

		.content {
			margin-left: 30rpx;
			border: 1rpx solid #CCCCCC;
			width: 90%;
			height: 55rpx;
		}
	}

	.noteZhaiyao {
		.title {
			font-size: 35rpx;
			font-weight: 600;
		}

		.content {
			textarea {
				margin-left: 30rpx;
				border: 1rpx solid #CCCCCC;
				width: 90%;
				height: 105rpx;
			}
		}
	}

	.noteContent {
		// border: 1rpx solid #CCCCCC;
		width: 90%;

		// margin: 0 auto;
		.title {
			font-size: 35rpx;
			font-weight: 600;

		}

		.buttonarea {
			display: flex;
			justify-content: space-between;
			align-items: center;
			margin-left: 10vw;

			button {
				color: white;
				background-color: #4A90E2;
			}
		}
	}

	.lessons {
		// margin: 0 auto;
		// width: 80%;
		// padding-left: 10rpx;
	}

	.page-body {
		// height: calc(100vh - var(--window-top) - var(--status-bar-height));

		height: 55vh;
		width: 90vw;
		// margin-left: 15rpx;

		border: 1rpx solid #CCCCCC;
	}

	.wrapper {
		// height: 100%;
	}

	.editor-wrapper {
		// height: calc(100vh - var(--window-top) - var(--status-bar-height) - 140px);
		height: 50vh;
		background: #fff;
	}

	.iconfont {
		display: inline-block;
		// padding: 8px 8px;
		width: 24px;
		height: 5px;
		cursor: pointer;
		font-size: 20px;
	}

	.toolbar {
		// display: none;
		margin-bottom: -150rpx;
		box-sizing: border-box;
		// margin-right: 30rpx;
		border-bottom: 1rpx solid #CCCCCC;
		// height: 10vh;
		font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
	}

	.ql-container {
		box-sizing: border-box;
		// padding: 12px 15px;
		width: 100%;
		min-height: 30vh;
		height: 100%;
		// margin-top: 20px;
		font-size: 16px;
		line-height: 1.5;
	}

	.ql-active {
		color: #06c;
	}

	.ql-editor .ql-blank {
		height: 100rpx;
	}

	.content-bottom {
		position: fixed;
		bottom: 0;

		background-color: #f6f6f6;
		width: 100%;
		height: 9vh;
		display: flex;
		// align-items: center;
		padding-top: 20rpx;
		justify-content: center;

		button {
			// position: absolute;
			width: 43vh;
			height: 80rpx;
			border-radius: 20rpx;
			font-size: 14px;
			line-height: 80rpx;
			// text-align: center;
			// margin-left: 20rpx;

		}
	}
</style>